﻿#ifndef ROBOTSTATUS_H
#define ROBOTSTATUS_H

#include <QObject>

#include "RobProtocol.h"
#include "RobotBase.h"

namespace robokit {

    using RobotStatusStopCallBack = std::function<void()>;
    using RobotStatusRelocCallBack = std::function<void()>;
    using RobotStatusCallBack= std::function<void()>;

/**
 * @brief 完整状态数据（来自 1100 命令 robot_status_all1，包含所有数据）
 */
struct RobotStatusAll1Data {
    // ========== 运行模式和位置 ==========
    int mode{0};
    double x{0.0}, y{0.0}, angle{0.0}, confidence{0.0};
    QString currentStation, lastStation;

    // ========== 速度信息 ==========
    double vx{0.0}, vy{0.0}, w{0.0}, steer{0.0}, spin{0.0};
    double r_vx{0.0}, r_vy{0.0}, r_w{0.0}, r_steer{0.0}, r_spin{0.0};

    // ========== 阻挡和减速 ==========
    bool isStop{false}, blocked{false}, slowed{false};
    int blockReason{0}, slowReason{0};
    double blockX{0.0}, blockY{0.0}, slowX{0.0}, slowY{0.0};
    int blockUltrasonicId{0}, blockDi{0}, slowUltrasonicId{0}, slowDi{0};

    // ========== 区域和路径 ==========
    QStringList areaIds;
    QJsonArray path;
    QString target_id;
    QStringList finished_paths;
    QStringList unfinished_paths;
    QString current_map;
    // ========== 急停和传感器 ==========
    bool emergency{false}, driverEmc{false};
    QJsonArray digitalInputs, digitalOutputs;

    // ========== 姿态 ==========
    double yaw{0.0}, roll{0.0}, pitch{0.0};

    // ========== 任务信息 ==========
    int taskStatus{0}, taskType{0};
    QString targetId;
    QJsonArray targetPoint;
    QStringList unfinishedPath, finishedPath;

    // ========== 传感器详细数据 ==========
    QJsonArray ultrasonicNodes, pgvs, lasers;

    // ========== 错误和报警 ==========
    QJsonArray fatals, errors, warnings, notices;

    // ========== 里程信息 ==========
    double odo{0.0};              // 累计行驶里程 (m)
    double todayOdo{0.0};         // 今日累计行驶里程 (m)

    // ========== 运行时间 ==========
    double runTime{0.0};          // 本次运行时间 (ms)
    double totalRunTime{0.0};     // 累计运行时间 (ms)

    // ========== 控制器状态 ==========
    double controllerTemp{0.0};   // 控制器温度 (℃)
    double controllerHumi{0.0};   // 控制器湿度 (%)
    double controllerVoltage{0.0}; // 控制器电压 (V)

    // ========== 电池信息 ==========
    double batteryLevel{0.0};     // 电池电量 [0, 1]
    double batteryTemp{0.0};      // 电池温度 (℃)
    bool charging{false};         // 是否充电
    double voltage{0.0};          // 电压 (V)
    double current{0.0};          // 电流 (A)
    double maxChargeVoltage{0.0}; // 最大充电电压 (V)
    double maxChargeCurrent{0.0}; // 最大充电电流 (A)
    bool manualCharge{false};     // 是否连接手动充电器
    bool autoCharge{false};       // 是否连接自动充电桩
    double batteryCycle{0.0};     // 电池循环次数

    // ========== 系统状态 ==========
    int relocStatus{0};           // 定位状态 (0失败, 1成功, 2正在重定位, 3完成)
    int loadmapStatus{0};         // 载入地图状态 (0失败, 1成功, 2正在载入)
    int slamStatus{0};            // SLAM状态
    

    // ========== API信息 ==========
    int retCode{0};
    QString createOn, errMsg;
    QDateTime uploadTime;
};

/**
 * @brief 核心状态数据（来自 1101 命令 robot_status_all2，高频）
 */
struct RobotStatusAll2Data {
    // 运行模式和位置
    int mode{0};
    double x{0.0}, y{0.0}, angle{0.0}, confidence{0.0};
    QString currentStation, lastStation;

    // 速度信息
    double vx{0.0}, vy{0.0}, w{0.0}, steer{0.0}, spin{0.0};
    double r_vx{0.0}, r_vy{0.0}, r_w{0.0}, r_steer{0.0}, r_spin{0.0};

    // 阻挡和减速
    bool isStop{false}, blocked{false}, slowed{false};
    int blockReason{0}, slowReason{0};
    double blockX{0.0}, blockY{0.0}, slowX{0.0}, slowY{0.0};
    int blockUltrasonicId{0}, blockDi{0}, slowUltrasonicId{0}, slowDi{0};

    // 区域和路径
    QStringList areaIds;
    QJsonArray path;

    // 急停和传感器
    bool emergency{false}, driverEmc{false};
    QJsonArray digitalInputs, digitalOutputs;

    // 姿态
    double yaw{0.0}, roll{0.0}, pitch{0.0};

    // 任务信息
    int taskStatus{0}, taskType{0};
    QString targetId;
    QJsonArray targetPoint;
    QStringList unfinishedPath, finishedPath;

    // 传感器详细数据
    QJsonArray ultrasonicNodes, pgvs, lasers;

    // 错误和报警
    QJsonArray fatals, errors, warnings, notices;

    // API信息
    int retCode{0};
    QString createOn, errMsg;
    QDateTime uploadTime;
};

/**
 * @brief 详细状态数据（来自 1102 命令 robot_status_all3，低频）
 */
struct RobotStatusAll3Data {
    // 里程信息
    double odo{0.0};              // 累计行驶里程 (m)
    double todayOdo{0.0};         // 今日累计行驶里程 (m)

    // 运行时间
    double runTime{0.0};          // 本次运行时间 (ms)
    double totalRunTime{0.0};     // 累计运行时间 (ms)

    // 控制器状态
    double controllerTemp{0.0};   // 控制器温度 (℃)
    double controllerHumi{0.0};   // 控制器湿度 (%)
    double controllerVoltage{0.0}; // 控制器电压 (V)

    // 电池信息
    double batteryLevel{0.0};     // 电池电量 [0, 100]
    double batteryTemp{0.0};      // 电池温度 (℃)
    bool charging{false};         // 是否充电
    double voltage{0.0};          // 电压 (V)
    double current{0.0};          // 电流 (A)
    double maxChargeVoltage{0.0}; // 最大充电电压 (V)
    double maxChargeCurrent{0.0}; // 最大充电电流 (A)
    bool manualCharge{false};     // 是否连接手动充电器
    bool autoCharge{false};       // 是否连接自动充电桩
    double batteryCycle{0.0};     // 电池循环次数

    // 系统状态
    int relocStatus{0};           // 定位状态 (0失败, 1成功, 2正在重定位, 3完成)
    int loadmapStatus{0};         // 载入地图状态 (0失败, 1成功, 2正在载入)
    int slamStatus{0};            // SLAM状态

    // API信息
    int retCode{0};
    QString createOn, errMsg;
    QDateTime uploadTime;
};

class RobotStatus : public RobotBase
{
    Q_OBJECT
public:
    double angle;
    double confidence;
    QString current_station;
    QString last_station;
    QString target_id;
    //导航类型, 0 = 没有导航, 1 = 自由导航到任意点, 2 = 自由导航到站点, 3 = 路径导航到站点, 7 = 平动转动, 100 = 其他
    double task_type;
    //	0 = NONE, 1 = WAITING(目前不可能出现该状态), 2 = RUNNING, 3 = SUSPENDED, 4 = COMPLETED, 5 = FAILED, 6 = CANCELED
    double task_status;
    double r_vx;
    double r_w;
    bool locked;
public:
    RobotStatus();

    void setDefaultAddress(const QString &newDefaultAddress);
    void setDefaultTcpPort(quint16 newDefaultTcpPort);

    void set_default_all1_req_obj(bool return_laser);
    void set_stop_call_back(RobotStatusStopCallBack func);
    void set_stop_station_call_back(QString station,RobotStatusStopCallBack func);
    void set_reloc_call_back(RobotStatusRelocCallBack func);
    void set_relocing_call_back(RobotStatusRelocCallBack func);
    void set_switch_map_call_back(RobotStatusCallBack func);
    

    void robot_status_all1_req_get();
    void robot_status_info_req_get();
    void robot_status_run_req_get();
    void robot_status_loc_req_get();
    void robot_status_speed_req_get();
    void robot_status_block_req_get();
    void robot_status_battery_req_get();
    void robot_status_motor_req_get();
    void robot_status_laser_req_get();
    void robot_status_area_req_get();

    void robot_status_area_res_get();

    void robot_status_slam_req_get(const QJsonObject &obj);
    void robot_status_jack_req_get(const QJsonObject& obj);

    void robot_status_roller_req_get(const QJsonObject &obj);

    void robot_status_map_req_get();
    void robot_status_map_req_get(std::function<void(uint16_t revCommand,QByteArray&)> callback);
    void robot_status_station_req_get();
    //void robot_status_downloadfile_req_get(const QJsonObject& obj);
    void robot_status_model_req_get(const QJsonObject& obj);
    void robot_status_params_req_get(const QJsonObject &obj);
    void robot_status_transparent_data_req_get(const QJsonObject &obj);
    void robot_status_armstatus_req_get(const QJsonObject &obj);
    void robot_status_alarm_req(const QJsonObject &obj);
    void robot_status_alarm_rep_get(const QJsonObject &obj);
    void robot_status_all1_req_get(const QJsonObject &obj);
    void robot_status_all2_req_get(const QJsonObject &obj);
    void robot_status_downloadfile_req_get(const QJsonObject &obj);
    void robot_status_script_info_req_get(const QJsonObject &obj);
    void robot_status_script_detailslist_req_get(const QJsonObject &obj);
    void robot_status_map_req_get(const QJsonObject &obj);
    void robot_status_battery_req_get(const QJsonObject &obj);
    void robot_status_sound_req_get(const QJsonObject &obj);
    void robot_status_motor_req_get(const QJsonObject &obj);
    void robot_status_laser_req_get(const QJsonObject &obj);
    void robot_status_emergency_req_get(const QJsonObject &obj);
    void robot_status_io_req_get(const QJsonObject &obj);
    void robot_status_imu_req_get(const QJsonObject &obj);
    void robot_status_rfid_req_get(const QJsonObject &obj);
    void robot_status_ultrasonic_req_get(const QJsonObject &obj);
    void robot_status_pgv_req_get(const QJsonObject &obj);
    void robot_status_encoder_req_get(const QJsonObject &obj);
    void robot_status_task_req_get(const QJsonObject &obj);
    void robot_status_task_status_package_req_get(const QJsonObject &obj);
    void robot_status_reloc_req_get(const QJsonObject &obj);
    void robot_status_loadmap_req_get(const QJsonObject &obj);
    void robot_status_fork_req_get(const QJsonObject &obj);
    void robot_status_dispatch_req_get(const QJsonObject &obj);
    void robot_status_all3_req_get(const QJsonObject &obj);
    void robot_status_current_lock_req_get(const QJsonObject &obj);

    void robot_status_mapmd5_req_get(const QJsonObject &obj);
    void robot_status_uploadfile_req_get(const QJsonObject &obj);
    void robot_status_listfile_req_get(const QJsonObject &obj);
    void robot_status_script_args_req_get(const QJsonObject &obj);
    void robot_status_armcalculate_req_get(const QJsonObject &obj);
    void robot_status_armtask_req_get(const QJsonObject &obj);
    void robot_status_armmove_req_get(const QJsonObject &obj);
    void robot_status_armoperation_req_get(const QJsonObject &obj);
    void robot_status_canframe_req_get(const QJsonObject &obj);
    void robot_status_gnsscheck_req_get(const QJsonObject &obj);
    void robot_status_gnss_list_req_get(const QJsonObject &obj);
    void robot_status_station_req_get(const QJsonObject &obj);
public Q_SLOTS:
    bool initConnection();
    bool checkConnection();
    void _SendDataForTest();
    void getError(QString msg);

signals:
    void updatePosition2();
    void updatePosition(double x, double y,double angle);
    void singal_sendToServerStatus(const QJsonObject&);

    // 状态更新信号 - 传递解析后的结构体数据
    void statusAll1Updated(const robokit::RobotStatusAll1Data& data);  // 1100 命令响应（完整状态）
    void statusAll2Updated(const robokit::RobotStatusAll2Data& data);  // 1101 命令响应（核心状态）
    void statusAll3Updated(const robokit::RobotStatusAll3Data& data);  // 1102 命令响应（详细状态）
private:

    RProtocol m_protocol;
    QString defaultAddress;
    quint16 defaultTcpPort;
    QByteArray m_receiveData;//来自tcp返回的数据
    //默认请求
    QByteArray robot_status_all1_default_req_obj;

    RobotStatusStopCallBack stop_call_back_func;
    RobotStatusRelocCallBack reloc_call_back_func;
    RobotStatusRelocCallBack relocing_call_back_func;
    RobotStatusCallBack switch_map_call_back_func;
    QString stop_station_for_call_back;
    RobotStatusCallBack stop_station_call_back;
    void robot_status_info_res_receive(uint16_t revCommand, QByteArray& receivedata);
    void robot_status_run_res_receive(uint16_t revCommand, QByteArray& receivedata);
    void robot_status_loc_res_receive(uint16_t revCommand, QByteArray& receivedata);
    void robot_status_speed_res_receive(uint16_t revCommand, QByteArray& receivedata);
    void robot_status_block_res_receive(uint16_t revCommand, QByteArray& receivedata);
    void robot_status_battery_res_receive(uint16_t revCommand, QByteArray& receivedata);
    void robot_status_motor_res_receive(uint16_t revCommand, QByteArray& receivedata);
    void robot_status_laser_res_receive(uint16_t revCommand, QByteArray& receivedata);
    void robot_status_area_res_receive(uint16_t revCommand, QByteArray& receivedata);
    void robot_status_io_res_receive(uint16_t revCommand, QByteArray& receivedata);
    void robot_status_imu_res_receive(uint16_t revCommand, QByteArray& receivedata);
    void robot_status_emergency_res_receive(uint16_t revCommand, QByteArray& receivedata);
    void robot_status_rfid_res_receive(uint16_t revCommand, QByteArray& receivedata);
    void robot_status_ultrasonic_res_receive(uint16_t revCommand, QByteArray& receivedata);
    void robot_status_pgv_res_receive(uint16_t revCommand, QByteArray& receivedata);
    void robot_status_encoder_res_receive(uint16_t revCommand, QByteArray& receivedata);
    void robot_status_task_req_receive(uint16_t revCommand, QByteArray& receivedata);
    void robot_status_task_status_package_res(uint16_t revCommand, QByteArray& receivedata);
    void robot_status_reloc_res_receive(uint16_t revCommand, QByteArray& receivedata);
    void robot_status_loadmap_res_receive(uint16_t revCommand, QByteArray& receivedata);
    void robot_status_slam_res_receive(uint16_t revCommand, QByteArray& receivedata);
    void robot_status_jack_res_receive(uint16_t revCommand, QByteArray& receivedata);
    void robot_status_fork_req_receive(uint16_t revCommand, QByteArray& receivedata);
    void robot_status_roller_res_receive(uint16_t revCommand, QByteArray& receivedata);
    void robot_status_dispatch_res_receive(uint16_t revCommand, QByteArray& receivedata);
    void robot_status_all3_res_receive(uint16_t revCommand, QByteArray& receivedata);
    void robot_status_current_lock_res_receive(uint16_t revCommand, QByteArray& receivedata);
    void robot_status_map_res_receive(uint16_t revCommand, QByteArray& receivedata);
    void robot_status_station_res_receive(uint16_t revCommand, QByteArray& receivedata);
    void robot_status_motor_req_receive(uint16_t revCommand, QByteArray& receivedata);
    void robot_status_params_res_receive(uint16_t revCommand, QByteArray& receivedata);
    void robot_status_uploadfile_res_receive(uint16_t revCommand, QByteArray& receivedata);
    void robot_status_downloadfile_res_receive(uint16_t revCommand, QByteArray& receivedata);
    void robot_status_listfile_res_receive(uint16_t revCommand, QByteArray& receivedata);
    void robot_status_script_info_res_receive(uint16_t revCommand, QByteArray& receivedata);
    void robot_status_script_detailslist_res_receive(uint16_t revCommand, QByteArray& receivedata);
    void robot_status_script_args_res_receive(uint16_t revCommand, QByteArray& receivedata);
    void robot_status_transparent_data_res(uint16_t revCommand, QByteArray& receivedata);
    void robot_status_armstatus_res_receive(uint16_t revCommand, QByteArray& receivedata);
    void robot_status_armmove_res_receive(uint16_t revCommand, QByteArray& receivedata);
    void robot_status_armtask_res_receive(uint16_t revCommand, QByteArray& receivedata);
    void robot_status_armmove_rep_receive(uint16_t revCommand, QByteArray& receivedata);
    void robot_status_armoperation_res_receive(uint16_t revCommand, QByteArray& receivedata);
    void robot_status_canframe_res(uint16_t revCommand, QByteArray& receivedata);
    void robot_status_gnsscheck_res_receive(uint16_t revCommand, QByteArray& receivedata);
    void robot_status_gnss_list_res_receive(uint16_t revCommand, QByteArray& receivedata);
    void robot_status_sound_res_receive(uint16_t revCommand, QByteArray& receivedata);
    void robot_status_model_res_receive(uint16_t revCommand, QByteArray& receivedata);
    void robot_status_alarm_res(uint16_t revCommand, QByteArray& receivedata);
    void robot_status_alarm_res_receive(uint16_t revCommand, QByteArray& receivedata);
   
    void robot_status_all1_res_receive(uint16_t revCommand, QByteArray& receivedata);
    void robot_status_all2_res_receive(uint16_t revCommand, QByteArray& receivedata);
    void robot_status_transparent_data_res_receive(uint16_t revCommand, QByteArray& receivedata);
};
}


#endif // ROBOTSTATUS_H
